package com.slfx.idgen.demo.idgen.config;

import com.slfx.idgen.demo.idgen.datetime.DatetimeIdServer;
import com.slfx.idgen.demo.idgen.exception.GenIdException;
import com.slfx.idgen.demo.idgen.properties.UUIDGeneratorProperties;
import com.slfx.idgen.demo.idgen.snowflake.SnowflakeServer;
import com.slfx.idgen.demo.idgen.uuid.CachedUUIDGenerator;
import com.slfx.idgen.demo.idgen.uuid.UUIDGenerator;
import com.slfx.idgen.demo.idgen.customid.CustomIdClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(UUIDGeneratorProperties.class)
public class IdFactory implements ApplicationContextAware, InitializingBean {

    private final Logger logger = LoggerFactory.getLogger(IdFactory.class);

    private ApplicationContext applicationContext;

    private static UUIDGenerator uuidGenerator;

    private static CachedUUIDGenerator cachedUUIDGenerator;

    private static SnowflakeServer snowflakeServer;

    private static CustomIdClient customIdClient;

    private static DatetimeIdServer datetimeIdServer;

    private UUIDGeneratorProperties uuidGeneratorProperties;

    public IdFactory(UUIDGeneratorProperties uuidGeneratorProperties){
        this.uuidGeneratorProperties = uuidGeneratorProperties;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        uuidGenerator = (UUIDGenerator) applicationContext.getBean("uUIDGenerator");
        if (uuidGeneratorProperties.isCached()) {
            cachedUUIDGenerator = (CachedUUIDGenerator) applicationContext.getBean("cachedUUIDGenerator");
        }
        snowflakeServer = (SnowflakeServer) applicationContext.getBean("snowflakeServer");
        customIdClient = (CustomIdClient) applicationContext.getBean("customIdClient");
        datetimeIdServer = (DatetimeIdServer)applicationContext.getBean("datetimeIdServer");
        logger.info("初始化id工厂IdFactory成功");
    }

    public static class UUID {
        public static String nextUUID() {
            return uuidGenerator.getNextUUID();
        }
    }

    public static class CachedUUID {
        public static String nextUUID() {
            if (uuidGenerator == null) {
                throw new GenIdException("带缓存的uuid需要在配置属性开启");
            }
            return cachedUUIDGenerator.getNextUUID();
        }
    }

    public static class Snowflake {

        public static long nextId() {
            return snowflakeServer.nextId();
        }

        public static String nextPrefixId(String prefix) {
            return snowflakeServer.nextPrefixId(prefix);
        }
    }

    public static class CustomId {

        public static long nextId(int length) {
            return customIdClient.getNextId(length);
        }

        public static String nextPrefixId(String prefix, int length) {
            return customIdClient.getNextStringId(prefix, length);
        }
    }

    public static class DatetimeId{

        public static String nextId(){
            return datetimeIdServer.nextId();
        }

        public static String nextPrefixId(String prefix){
            return datetimeIdServer.nextPrefixId(prefix);
        }
    }
}
